/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.StringTokenizer;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import local.AttemptFacadeLocal;
import local.IndustryFacadeLocal;
import local.PublicUserFacadeLocal;
import local.QuestionFacadeLocal;
import model.Attempt;
import model.Industry;
import model.PublicUser;
import model.Question;
import model.Scoring;
import model.Theme;
import model.ThemeScore;
import util.Csv;
import util.JsonReturnMsg;
import util.JsonReturnTable;

/**
 *
 * @author Randy
 */
@WebServlet(name = "AttemptServlet", urlPatterns = {"/AttemptServlet"})
public class AttemptServlet extends HttpServlet {

    @EJB
    AttemptFacadeLocal aFacade;
    @EJB
    PublicUserFacadeLocal puFacade;
    @EJB
    QuestionFacadeLocal qFacade;
    @EJB
    IndustryFacadeLocal iFacade;
    Gson gson = new Gson();
    private String json;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");

        try {
            if (action.equals("getAttempts")) {
                getAttempts(request, response);

            } else if (action.equals("updateAttempt")) {
                updateAttempt(request, response);

            } else if (action.equals("deleteAttempt")) {
                deleteAttempt(request, response);

            } else if (action.equals("attemptDetail")) {
                attemptDetail(request, response);

            } else if (action.equals("generateCSV")) {
                generateCSV(request, response);

            } else if (action.equals("getAttemptThemeScore")) {
                getAttemptThemeScore(request, response);

            } else if (action.equals("getAttemptScoring")) {
                getAttemptScoring(request, response);
            }

        } catch (Exception ex) {
            json = gson.toJson(new JsonReturnMsg("Error", ex.getMessage(), "error"));
            response.getWriter().println(json);
        } finally {
            response.getWriter().close();
        }
    }

    private void getAttempts(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String status = request.getParameter("survey_status");
        String industry = request.getParameter("industry");

        ArrayList<Attempt> aList = aFacade.getAttempts(Long.parseLong(industry), status);

        for (Attempt att : aList) {
            att.setPdfStream(null);
            att.setScoring(null);
            att.setThemeScore(null);
            att.setIndustry(null);

        }

        json = gson.toJson(new JsonReturnTable(aList.size() + "", aList));
        response.getWriter().println(json);
    }

    private void updateAttempt(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String attempt_id = request.getParameter("attempt_id");
        String status = request.getParameter("status");

        aFacade.updateAttempt(Long.parseLong(attempt_id), status);

        json = gson.toJson(new JsonReturnMsg("Edit Attempt", "Attempt updated", "info"));
        response.getWriter().println(json);
    }

    private void deleteAttempt(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String attempt_id = request.getParameter("attempt_id");

        aFacade.deleteAttempt(Long.parseLong(attempt_id));

        json = gson.toJson(new JsonReturnMsg("Delete Attempt", "Attempt deleted", "info"));
        response.getWriter().println(json);
    }

    private void attemptDetail(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String attempt_id = request.getParameter("attempt_id");

        Attempt a = aFacade.getAttempt(Long.parseLong(attempt_id));
        
        a.setPdfStream(null);
        a.setScoring(null);
        a.setThemeScore(null);
        a.setIndustry(null);

        json = gson.toJson(a);
        response.getWriter().println(json);
    }

    private void getAttemptThemeScore(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String attempt_id = request.getParameter("attempt_id");

        Attempt a = aFacade.getAttempt(Long.parseLong(attempt_id));

        json = gson.toJson(new JsonReturnTable(a.getThemeScore().size() + "", new ArrayList(a.getThemeScore())));
        response.getWriter().println(json);
    }

    private void getAttemptScoring(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String attempt_id = request.getParameter("attempt_id");

        Attempt a = aFacade.getAttempt(Long.parseLong(attempt_id));

        json = gson.toJson(new JsonReturnTable(a.getScoring().size() + "", new ArrayList(a.getScoring())));
        response.getWriter().println(json);
    }

    private void generateCSV(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String industry = request.getParameter("industry");

        ArrayList csvFileContent = new ArrayList();
        ArrayList headerContent = new ArrayList();

        //build header for general details
        headerContent.add("Time");
        headerContent.add("IP Add.");
        headerContent.add("Country");
        headerContent.add("Industry");
        headerContent.add("Name");
        headerContent.add("Title");
        headerContent.add("Email");
        headerContent.add("Company");
        headerContent.add("Company Size");
        headerContent.add("IT Dept Size");
        headerContent.add("Status");
        headerContent.add("Viewed");

        ArrayList<Industry> iList = new ArrayList(iFacade.findAll());

        //build header for industry question, firm question & average score
        for (Industry i : iList) {
            if (i.getId() == Long.parseLong(industry)) {
                for (Theme t : i.getTheme()) {
                    headerContent.add("T" + t.getTheme_id() + " IQ");
                }

                for (Theme t : i.getTheme()) {
                    headerContent.add("T" + t.getTheme_id() + " FQ");
                }

                for (Theme t : i.getTheme()) {
                    headerContent.add("T" + t.getTheme_id() + " AvgS.");
                }
            }
        }

        //build header for theme question
        for (Industry i : iList) {
            if (i.getId() == Long.parseLong(industry)) {
                for (Theme t : i.getTheme()) {
                    for (Question q : t.getQuestion()) {
                        headerContent.add("T" + t.getTheme_id() + " Q" + q.getQns_id());
                    }
                }
            }
        }

        csvFileContent.add(headerContent);

        ArrayList<PublicUser> puList = puFacade.getAllPublicUser();

        for (PublicUser pu : puList) {
            for (Attempt a : pu.getAttempt()) {
                if (a.getIndustry().getId() == Long.parseLong(industry)) {
                    ArrayList rowContent = new ArrayList();

                    //build content for general details
                    rowContent.add(a.getTimestamps());
                    rowContent.add(a.getIp_address());
                    rowContent.add(a.getCountry());
                    rowContent.add(a.getIndustry().getName());
                    rowContent.add(pu.getName() == null ? "" : pu.getName());
                    rowContent.add(a.getTitle() == null ? "" : a.getTitle());
                    rowContent.add(pu.getEmail() == null ? "" : pu.getEmail());
                    rowContent.add(a.getCompany_name() == null ? "" : a.getCompany_name());
                    rowContent.add(a.getCompany_size() == null ? "" : a.getCompany_size());
                    rowContent.add(a.getIt_dept_size() == null ? "" : a.getIt_dept_size());
                    rowContent.add(a.getStatus().name());
                    rowContent.add(a.getAck().name());

                    //build content for industry question
                    for (int i = 12; i < 21; i++) {
                        for (ThemeScore ts : a.getThemeScore()) {
                            String header = "T" + ts.getTheme().getId() + " IQ";
                            if (header.equals(headerContent.get(i))) {
                                rowContent.add(ts.getInd_score());
                                break;
                            }
                        }
                    }

                    //build content for firm question
                    for (ThemeScore tsCheck : a.getThemeScore()) {
                        if (tsCheck.getFirm_score() == null) {
                            for (int i = 21; i < 30; i++) {
                                rowContent.add("");
                            }
                            break;
                        } else {
                            for (int i = 21; i < 30; i++) {
                                for (ThemeScore ts : a.getThemeScore()) {
                                    String header = "T" + ts.getTheme().getId() + " FQ";
                                    if (header.equals(headerContent.get(i))) {
                                        rowContent.add(ts.getFirm_score());
                                        break;
                                    }
                                }
                            }
                            break;
                        }
                    }

                    //build content for average score
                    if (a.getScoring().isEmpty()) {
                        for (int i = 30; i < 39; i++) {
                            rowContent.add("");
                        }
                    } else {
                        for (int i = 30; i < 39; i++) {
                            for (ThemeScore ts : a.getThemeScore()) {
                                String header = "T" + ts.getTheme().getId() + " AvgS.";
                                if (header.equals(headerContent.get(i))) {
                                    rowContent.add(ts.getFirm_score());
                                    break;
                                }
                            }
                        }
                    }

                    //build content for survey question
                    if (a.getScoring().isEmpty()) {
                        for (int i = 39; i < headerContent.size(); i++) {
                            rowContent.add("");
                        }
                    } else {
                        for (int i = 39; i < headerContent.size(); i++) {
                            boolean match = false;
                            for (Scoring s : a.getScoring()) {
                                StringTokenizer token = new StringTokenizer(headerContent.get(i).toString(), " ");
                                String subString = "";
                                while (token.hasMoreTokens()) {
                                    subString = token.nextToken();
                                }
                                String header = "Q" + s.getQuestion().getQns_id();
                                if (header.equals(subString)) {
                                    rowContent.add(s.getScore());
                                    match = true;
                                    break;
                                }
                            }

                            if (match == false) {
                                rowContent.add("");
                            }
                        }
                    }

                    csvFileContent.add(rowContent);
                }
            }
        }

        Csv csvFile = new Csv();
        csvFile.generateCsvFile(csvFileContent);

        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        String currentTimestamp = dateFormat.format(date);

        response.setContentType("application/csv");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + "Ind-" + industry + "-" + currentTimestamp + ".csv" + "\";");

        File f = new File("Attempts.csv");
        FileInputStream fis = new FileInputStream(f);
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        String strLine;

        while ((strLine = br.readLine()) != null) {
            response.getWriter().write(strLine);
            response.getWriter().write(System.getProperty("line.separator"));
        }

        response.getWriter().flush();
        br.close();
        isr.close();
        fis.close();
        f.delete();
    }

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
